﻿package njClass.bat{
	import flash.geom.Matrix;
	import flash.display.DisplayObject;
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Shape;
	import flash.geom.Point;
	import flash.display.Graphics;
	import flash.display.GradientType;
	import flash.display.Sprite;
	import flash.display.Stage;
	import flash.geom.Rectangle;
	import flash.geom.ColorTransform;
	import flash.filters.ColorMatrixFilter;
	import flash.events.Event;
	
	public class ImagePlus {
		private static var isHitTest:Boolean;
		private static var bc:BitmapData;
		private static var r_lum:Number = 0.3086;
		private static var g_lum:Number = 0.6094;
		private static var b_lum:Number = 0.0820;
		
		//翻转图像(HORIZONTAL：水平翻转；VERTICAL：垂直翻转）
		public static function flip(display:DisplayObject,VERTICAL:Boolean=true):void {
			var m:Matrix = display.transform.matrix;
			if(VERTICAL){
				m.d = -1;
				m.ty = display.height + display.y;
			}else{
				m.a = -1;
				m.tx = display.width + display.x;	
			}
			display.transform.matrix = m;
		}
		
		//水面镜像（true：垂直镜像；false：水平镜像）
		public static function createRef(p_source:DisplayObject,VERTICAL:Boolean=true,isUpData:Boolean=false):void {
			var bd:BitmapData=new BitmapData(p_source.width,p_source.height,true,0);
			var mtx:Matrix=new Matrix();
			if (VERTICAL) {
				mtx.d=-1;
				mtx.ty=bd.height;
			} else {
				mtx.a=-1;
				mtx.tx=bd.width;
			}
			bd.draw(p_source,mtx);
			var width:int=bd.width;
			var height:int=bd.height;
			mtx=new Matrix();
			if (VERTICAL) {
				mtx.createGradientBox(width,height,0.5 * Math.PI);
			} else {
				mtx.createGradientBox(width,height);
			}
			var shape:Shape = new Shape();
			shape.graphics.beginGradientFill(GradientType.LINEAR,[0,0],[0.9,0.2],[0,0xFF],mtx);
			shape.graphics.drawRect(0,0,width,height);
			shape.graphics.endFill();
			var mask_bd:BitmapData=new BitmapData(width,height,true,0);
			mask_bd.draw(shape);
			bd.copyPixels(bd,bd.rect,new Point(0,0),mask_bd,new Point(0,0),false);
			var ref:Bitmap=new Bitmap();
			if (VERTICAL) {
				ref.x=p_source.x;
				ref.y=p_source.y+p_source.height;
			} else {
				ref.y=p_source.y;
				ref.x=p_source.x+p_source.width;
			}
			ref.bitmapData=bd;
			ref.name="ref";
			p_source.parent.addChild(ref);
			
			if(isUpData){
				shape.addEventListener(Event.ENTER_FRAME,checkData);
			}
			
			function checkData(evt:Event):void{
				p_source.parent.removeChild(p_source.parent.getChildByName("ref"));
				createRef(p_source,VERTICAL,false);
			}
		}
		
		//任意点投影
		public static function mirror(p_source:DisplayObject,windows:DisplayObject,ScaleX:Number=1.5,ScaleY:Number=1.5,shadow_name:String="shadow"):void {
			var bd:BitmapData=new BitmapData(p_source.width,p_source.height,true,0);
			var mtx:Matrix=new Matrix();
			//mtx.a=-1;
			//mtx.tx=bd.width;
			bd.draw(p_source,mtx);
			var width:int=windows.width*1.5;
			var height:int=windows.height*1.5;
			mtx=new Matrix();
			mtx.createGradientBox(width,height);
			var shape:Shape= new Shape();
			shape.graphics.beginGradientFill(GradientType.LINEAR,[0,0],[0.9,0.7],[0,0xFF],mtx);
			shape.graphics.drawRect(0,0,width,height);
			shape.graphics.endFill();
			var mask_bd:BitmapData=new BitmapData(width,height,true,0);
			mask_bd.draw(shape);
			bd.copyPixels(bd,bd.rect,new Point(0,0),mask_bd,new Point(0,0),false);
			var ref:Bitmap=new Bitmap();
			ref.y=(p_source.y-windows.y+windows.height*(ScaleY-1)/2)*(windows.height-p_source.height)/(ScaleY*windows.height-p_source.height);
			ref.x=(p_source.x-windows.x+windows.width*(ScaleX-1)/2)*(windows.width-p_source.width)/(ScaleX*windows.width-p_source.width);
			ref.bitmapData=bd;
			//ref.scaleX=1-0.05*ref.x;
			//ref.scaleY=1-0.05*ScaleY;
			if (Sprite(windows).getChildByName("mask")!=null) {
				Sprite(windows).removeChild(Sprite(windows).getChildByName("mask"));
			}
			var mask_mc:Sprite=new Sprite();
			mask_mc.name="mask";
			mask_mc.addChild(doDraw(windows.width,windows.height));
			Sprite(windows).addChild(mask_mc);
			ref.mask=mask_mc;
			ref.name=shadow_name;
			Sprite(windows).addChild(ref);
		}
		
		private static function doDraw(w:Number,h:Number,bgColor:uint=0x000000):Shape {
			var child:Shape=new Shape;
			child.graphics.beginFill(bgColor);
			child.graphics.drawRect(0,0,w,h);
			child.graphics.endFill();
			return child;
		}
		
		//像素级碰撞检测(type=0(单纯返回true/false)；type=1（生成交错图像）；mixColor：混合层颜色）
		public static function hitTest(Obj1:DisplayObject,Obj2:DisplayObject,type:int=0,Root:DisplayObject=null,mixColor:uint=0x000000):Boolean{
			var rect:Rectangle;
			
			var bmd1:BitmapData = new BitmapData(Obj1.width, Obj1.height, true, 0);
			bmd1.draw(Obj1, null, new ColorTransform(125, 125, 125, 1)); 
			var bmd2:BitmapData = new BitmapData(Obj2.width, Obj2.height, true, 0);
			bmd2.draw(Obj2, null, new ColorTransform(0, 0, 0, 1)); 
			var bx = (Obj1.x > Obj2.x) ? Obj2.x : Obj1.x;
			var by = (Obj1.y > Obj2.y) ? Obj2.y : Obj1.y;
			var bw = (Obj1.x > Obj2.x) ? Math.abs(Obj1.x-Obj2.x+Obj1.width) : Math.abs(Obj2.x-Obj1.x+Obj2.width);
			var bh = (Obj1.y > Obj2.y) ? Math.abs(Obj1.y-Obj2.y+Obj1.height) : Math.abs(Obj2.y-Obj1.y+Obj2.height);
			var bc1:BitmapData = new BitmapData(bw, bh, true, 0);
			var bc2:BitmapData = new BitmapData(bw, bh, true, 0);
			bc1.copyPixels(bmd1, bmd1.rect, new Point(0, 0), null, null, true);
			bc1.copyPixels(bmd2, bmd2.rect, new Point(Obj2.x-Obj1.x, Obj2.y-Obj1.y), null, null, true);
			bc2.copyPixels(bmd2, bmd2.rect, new Point(Obj2.x-Obj1.x, Obj2.y-Obj1.y), null, null, true);
			bc2.copyPixels(bmd1, bmd1.rect, new Point(0, 0), null, null, true);
			
			/*if (Sprite(Root).getChildByName("bmp1") != null) {
				Sprite(Root).removeChild(Sprite(Root).getChildByName("bmp1"));
			}
			var bmp1:Bitmap = new Bitmap(bc1, "auto", true);
			bmp1.name = "bmp1";
			bmp1.x=Obj1.x;
			bmp1.y=Obj1.y;
			Sprite(Root).addChild(bmp1);*/
			
			/*if(typeof(bc) == "object"){
				bc.dispose();
			}*/
			
			var _bc:Object = bc1.compare(bc2);
			if (_bc == 0) {
				return false;
			}else {
				bc = _bc as BitmapData;
			}
			//bc = bc1.compare(bc2);
			
			if(typeof(bc) == "object"){
				isHitTest=true;
				//trace(bc);
				if(type!=0){
					var colorT:ColorTransform=new ColorTransform();
					colorT.color=mixColor;
					bc.colorTransform(bc.rect, colorT);
					if (Sprite(Root).getChildByName("bmp") != null) {
						Sprite(Root).removeChild(Sprite(Root).getChildByName("bmp"));
					}
					var bmp:Bitmap = new Bitmap(bc, "auto", true);
					bmp.name = "bmp";
					bmp.x=Obj1.x;
					bmp.y=Obj1.y;
					Sprite(Root).addChild(bmp);
				}
			}else{
				isHitTest=false;
			}
			
			//bc.dispose();
			bc1.dispose();
			bc2.dispose();
			bc1 = null;
			bc2 = null;
			
			return isHitTest;
		}
		
		//设置饱和度(0-100);
		public static function setSaturation(obj:DisplayObject,s:int):void{
			var lis:Number=1-s;
			var irlum:Number = lis * r_lum;
			var iglum:Number = lis * g_lum;
			var iblum:Number = lis * b_lum;
			
			var mat:Array = new Array (irlum + s, iglum    , iblum    , 0, 0,
									   irlum    , iglum + s, iblum    , 0, 0,
									   irlum    , iglum    , iblum + s, 0, 0,
									   0        , 0        , 0        , 1, 0 );
			
			concat(obj,mat);
		}
		
		//设置亮度(-255 to 255)
		public static function setBrightness (obj:DisplayObject,r:int):void{
			var mat:Array;
			
			mat= new Array(1,0,0,0, r,
						   0,1,0,0, r,
						   0,0,1,0, r,
						   0,0,0,1, 0);
			
			concat(obj,mat);
		}
		
		//设置色彩反转效果(0-360)
		public static function setHue(obj:DisplayObject,rot:Number ):void{
			rot*=Math.PI/180;
			var c:Number = Math.cos(rot);
			var s:Number = Math.sin(rot);;
			var f1:Number = 0.213;
			var f2:Number = 0.715;
			var f3:Number = 0.072;
			var mat:Array = new Array((f1 + (c * (1 - f1))) + (s * (-f1)), (f2 + (c * (-f2))) + (s * (-f2)), (f3 + (c * (-f3))) + (s * (1 - f3)), 0, 0,
									  (f1 + (c * (-f1))) + (s * 0.143), (f2 + (c * (1 - f2))) + (s * 0.14), (f3 + (c * (-f3))) + (s * -0.283), 0, 0, (f1 + (c * (-f1))) + (s * (-(1 - f1))), (f2 + (c * (-f2))) + (s * f2), (f3 + (c * (1 - f3))) + (s * f3), 0,0,
                                      0, 0, 0, 1, 0,
                                      0, 0, 0, 0, 1);
			concat(obj,mat);
		}
		
		//变成黑白图片
		public static function desaturate(obj:DisplayObject):void{
			var mat:Array = new Array (r_lum, g_lum, b_lum, 0, 0,
									   r_lum, g_lum, b_lum, 0, 0,
									   r_lum, g_lum, b_lum, 0, 0,
									   0    , 0    , 0    , 1, 0 );
			
			concat(obj,mat);
		}
		
		//负片效果
		public static function threshold(obj:DisplayObject,t:Number):void{
			var mat:Array = new Array  (r_lum*256, g_lum*256, b_lum*256, 0,  -256*t,
										r_lum*256 ,g_lum*256, b_lum*256, 0,  -256*t,
										r_lum*256, g_lum*256, b_lum*256, 0,  -256*t,
										0, 0, 0, 1, 0 );
			concat(obj,mat);
		}
		
		//颜色反转
		public static function invert(obj:DisplayObject):void{
			var mat:Array = new Array ( -1 ,  0,  0, 0, 255,
									   0 , -1,  0, 0, 255,
									   0 ,  0, -1, 0, 255,
									   0 ,  0,  0, 1,   0);
			concat(obj,mat);
		}
		
		private static function concat(obj:DisplayObject,mat:Array):void{
			var colorMat:ColorMatrixFilter = new ColorMatrixFilter(mat);
			obj.filters = [colorMat];
		}
	}
}